package com.smp.support;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.smp.domain.DelayJobEntity;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;

/**
 * @author: fangxiaoyu
 * @date: 2021/6/24
 * @description:
 **/
@Slf4j
@Component
public class JobTimer {

    public static final String jobsTag = "delay_job";

    private RedissonClient client;

    private ApplicationContext context;

    private static ExecutorService executorService;

    @Autowired
    public JobTimer(RedissonClient client, ApplicationContext context) {
        this.client = client;
        this.context = context;
    }

    @PostConstruct
    public void startJobTimer() {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNamePrefix("delay-job-service").build();
        executorService = new ThreadPoolExecutor(1, 10, 30,
                TimeUnit.MINUTES, new LinkedBlockingQueue<>(10), namedThreadFactory);

        executorService.execute(new ExecutorTask());
    }

    class ExecutorTask implements Runnable {
        @SneakyThrows
        @Override
        public void run() {
            RBlockingQueue blockingQueue = client.getBlockingQueue(jobsTag);
            while (true) {
                try {
                    DelayJobEntity job = (DelayJobEntity) blockingQueue.take();
                    // 执行逻辑
                    ExecuteJob service = (ExecuteJob) context.getBean(job.getAClass());
                    service.execute(job);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
                // 防止疯狂打印日志
                TimeUnit.SECONDS.sleep(10);
            }
        }
    }

}
